﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Crawler.Core.Analyzer
{
    public class AnalyzerManager
    {
        private static Dictionary<string, Type> dicAnalyzers;
        private static List<AnalyzerInfo> analyzerInfos;

        static AnalyzerManager()
        {
            LoadAnalyzer();
        }
        private static void LoadAnalyzerTypes(Type filterType,Action<Type> action)
        {
            
            var dir = Environment.CurrentDirectory+ @"\bin\Debug\netcoreapp2.2";
            if (!Directory.Exists(dir)) dir = Environment.CurrentDirectory;
            var dlls = Directory.GetFiles(dir).Where(f => f.EndsWith(".dll"));
            foreach (var dll in dlls)
            {
                try
                {
                    var types = Assembly.LoadFile(dll).GetTypes().Where(t => t.GetInterfaces().Where(it => it == filterType).Count() > 0);
                    foreach (var type in types)
                    {
                        try
                        {
                            action?.Invoke(type);
                        }
                        catch (Exception ex)
                        {
                            //
                        }
                    }
                }
                catch (Exception ex)
                {
                    //
                }
            }
        }

        /// <summary>
        /// 调用注册器注册服务
        /// </summary>
        /// <param name="services"></param>
        internal static void Register(IServiceCollection services)
        {
            analyzerInfos = new List<AnalyzerInfo>();
            LoadAnalyzerTypes(typeof(IAnalyzerRegister), type =>
            {
                var obj = (IAnalyzerRegister)Activator.CreateInstance(type);
                obj.Register(services);
                analyzerInfos.AddRange(obj.AnalyzerInfos);
            });
            
        }

        /// <summary>
        /// 载入解析器
        /// </summary>
        private static void LoadAnalyzer()
        {
            dicAnalyzers = new Dictionary<string, Type>();

            LoadAnalyzerTypes(typeof(IAnalyzer), type =>
            {
                if (!dicAnalyzers.ContainsKey(type.FullName))
                {
                    dicAnalyzers.Add(type.FullName, type);
                }
            });
        }
        /// <summary>
        /// 获取解析器数据
        /// </summary>
        /// <returns></returns>
        public List<AnalyzerInfo> GetAnalyzerInfos()
        {
            return analyzerInfos.Select(a => a).ToList();//相当复制一份
        }
        /// <summary>
        /// 根据完整名称获取解析器
        /// </summary>
        /// <param name="fullname"></param>
        /// <returns></returns>
        public AnalyzerInfo GetAnalyzerInfoFullName(string fullname)
        {
            return analyzerInfos.Where(item => item.FullName == fullname).FirstOrDefault();
        }

        /// <summary>
        /// 根据完整名称获取解析器
        /// </summary>
        /// <param name="fullname"></param>
        /// <returns></returns>
        public Type GetAnalyzerTypeByFullName(string fullname)
        {
            return dicAnalyzers.Where(item => item.Key == fullname).FirstOrDefault().Value;
        }
    }
}
